#include "DoubleLinkList.h"
#include <stdio.h>
#include <stdlib.h>
#define true 1
#define false 0

int InitDLinkList(DLList *list)
{
    list->len=0;
    list->head=NULL;
    list->tail=NULL;
    return true;
}

Node *CreateNode(ElementType element)
{
    Node *newnode=(Node*)malloc(sizeof(Node));
    if(newnode==NULL)
    {
        printf("creatnode malloc error\n");
        return NULL;
    }
    newnode->data=element;
    newnode->next=NULL;
    newnode->prev=NULL;
    return newnode;
}


void InsertTail(DLList *list, ElementType element)
{
    Node *newnode=CreateNode(element);
    if(newnode==NULL)
    {
        printf("insertail createnode error\n");
        return;
    }
    if(list->len==0)
    {
        list->head=newnode;
        list->tail=newnode;
    }
    else
    {
        list->tail->next=newnode;
        newnode->prev=list->tail;
        list->tail=newnode;
    }
        list->len++;
}

void InsertHead(DLList *list, ElementType element)
{
    Node *newnode=CreateNode(element);
    if(newnode==NULL)
    {
        printf("insertail createnode error\n");
        return;
    }
    if(list->len==0)
    {
        list->head=newnode;
        list->tail=newnode;
    }
    else
    {
        list->head->prev=newnode;
        newnode->next=list->head;
        list->head=newnode;
    }
        list->len++;
}

int FindFirstByElement(DLList *list, ElementType element)
{
    int count=0;
    Node *TravelPoint=list->head;
    while(TravelPoint!=NULL)
    {
        if(TravelPoint->data==element)
        {
            return count;
        }
        count++;
        TravelPoint=TravelPoint->next;
    }
    return -1;
    
}

void RemoveByIndex(DLList *list, int index)
{
    if(index<0||index>=list->len)
    {
        printf("removebyindex invalid error\n");
        return;
    }
    if(index==0)
    {
        Node *temp=list->head;
        if(list->len==1)
        {
            free(temp);
            list->head=NULL;
            list->tail=NULL;
            list->len=0;
            return;
        }
        list->head=list->head->next;
        list->head->prev=NULL;
        free(temp);
        list->len--;
        return;
    }
    if(index==list->len-1)
    {
        Node *temp=list->tail;
        list->tail=list->tail->prev;
        list->tail->next=NULL;
        list->len--;
        free(temp);
        return;
    }
    Node *TravelPoint=list->head;
    while(index!=0)
    {
        TravelPoint=TravelPoint->next;
        index--;
    }
    
    TravelPoint->prev->next=TravelPoint->next;
    TravelPoint->next->prev=TravelPoint->prev;
    free(TravelPoint);
    list->len--;
}

void RemoveByElement(DLList *list, ElementType element)
{
    int count=FindFirstByElement(list,element);
    while(count!=-1)
    {
        RemoveByIndex(list,count);
        count=FindFirstByElement(list,element);
    }
}

void DLTrave(DLList *list,void (*func)(ElementType))
{

    Node *TravelPoint=list->head;
    while(TravelPoint!=NULL)
    {
        if(func!=NULL)
        {
            func(TravelPoint->data);
        }
        TravelPoint=TravelPoint->next;
    }
}

void FreeDLinkList(DLList *list,void (*func)(ElementType))
{
    while(list->head!=NULL)
    {
        Node *temp=list->head->next;
        func(list->head->data);
        free(list->head);
        list->head=temp;
    }
    list->len=0;
    list->head=NULL;
    list->tail=NULL;
}
int GetListLen(DLList *list)
{
    return list->len;
}
